package com.chengliang0315.locationtest.util.location;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.chengliang0315.locationtest.util.LogUtils;
import com.chengliang0315.locationtest.util.TimeUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.DecimalFormat;


/**
 * GPS卫星定位
 *
 * @author chengliang0315
 * @see <a>http://blog.csdn.net/chengliang0315</a>
 */
public class GPSLocation {

    private static final String TAG = "GPSLocation";
    private Location location;
    private static GPSLocation instance;
    private static Context mContext;
    private static LocationManager locationManager;
    private static LocationListener locationListener;

    private static OnGPSLocationRequestListener listener;

    public static GPSLocation getInstance(Context mContext) {
        if (instance == null) {
            instance = new GPSLocation(mContext);
        }
        return instance;
    }

    public void setOnGPSLocationRequestListener(OnGPSLocationRequestListener listener) {
        this.listener = listener;
    }

    public static LocationListener getLocationListener() {
        return locationListener;
    }

    private GPSLocation(Context mContext) {
        this.mContext = mContext;
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        initLocationListener();
        setLocationListener(locationListener);//这里的定位监听器可先设置，即使GPS处于关闭状态，当用户打开GPS的时候，将直接回调该接口
    }

    /**
     * 判断GPS导航是否打开.
     * @return true为打开
     */
    public boolean isOpenGPS() {
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    /**
     * 初始化定位监听
     */
    private void initLocationListener() {
        locationListener = new LocationListener() {

            /**
             * 位置信息变化时触发
             */
            @Override
            public void onLocationChanged(Location location) {
                //位置信息变化时触发
                LogUtils.i(TAG, "纬度：" + location.getLatitude() + "  经度：" + location.getLongitude()
                        + "  海拔：" + location.getAltitude() + "  时间：" +
                        TimeUtils.milliseconds2String(location.getTime(), TimeUtils.TimeFormat.yyyy_MM_dd_HH$mm$ss));
                GPSLocation.this.location = location;
            }

            /**
             * GPS状态变化时触发
             */
            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                LogUtils.i(provider);
                switch (status) {
                    //GPS状态为可见时
                    case LocationProvider.AVAILABLE:
                        LogUtils.i(TAG, "当前GPS状态为可见状态");
                        break;
                    //GPS状态为不在服务区
                    case LocationProvider.OUT_OF_SERVICE:
                        LogUtils.i(TAG, "当前GPS状态为不在服务区状态");
                        location = null;
                        break;
                    //GPS状态为暂停服务时
                    case LocationProvider.TEMPORARILY_UNAVAILABLE:
                        LogUtils.i(TAG, "当前GPS状态为暂停服务状态");
                        location = null;
                        break;
                }
            }

            /**
             * 被用户开启后调用
             */
            @Override
            public void onProviderEnabled(String provider) {
                LogUtils.i(TAG, "用户打开了GPS");
            }

            /**
             * 被用户关闭后调用
             */
            @Override
            public void onProviderDisabled(String provider) {
                LogUtils.i(TAG, "用户关闭了GPS");
                location = null;
            }
        };

    }

    /**
     * 通过LocationListener来获取Location信息
     */
    public void setLocationListener(LocationListener locationListener) {
        //判断权限是否允许
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        /**
         * 绑定监听
         * 参数1，设备：有GPS_PROVIDER和NETWORK_PROVIDER两种，前者是GPS,后者是GPRS以及WIFI定位
         * 参数2，位置更新的最小时间间隔，以毫秒为单位
         * 参数3，位置变化最小距离：当位置距离变化超过此值时，将更新位置信息,单位米
         * 参数4，监听
         * 备注：参数2和3，如果参数3不为0，则以参数3为准；参数3为0，则通过时间来定时更新；两者为0，则随时刷新
         */
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000, 1, locationListener);
    }

    /**
     * 移除
     */
    public void removeLocationListener(LocationListener locationListener) {
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        locationManager.removeUpdates(locationListener);
    }

    /**
     * 主动获取Location，通过以下方法获取到的是最后一次定位信息。
     * 注意：Location location=new Location(LocationManager.GPS_PROVIDER)方式获取的location的各个参数值都是为0。
     */
    public Location getLocation() {

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return location;
        }

        if (location == null){
            //获取最近的一次
            //如果之前没有定位信息，获取到的是null
            location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        }

        if (location != null) {
            LogUtils.i(TAG, "纬度：" + location.getLatitude() + "  经度：" + location.getLongitude()
                    + "  海拔：" + location.getAltitude() + "  时间：" +
                    TimeUtils.milliseconds2String(location.getTime(), TimeUtils.TimeFormat.yyyy_MM_dd_HH$mm$ss));
        }
        return location;
    }

    /**
     * 通过网络将经纬度解析为详细地理位置
     */
    public void requestLocation(){

        String url = "http://api.cellocation.com/regeo/?lat=%1$s&lon=%2$s&output=json";
        final Location location = getLocation();
        if (location == null){
            if (listener != null) {
                listener.onFailed();
            }
            return;
        }
        url = String.format(url,location.getLatitude(),location.getLongitude());

        LogUtils.i(url);
        StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                LogUtils.json(response);
                LocationInfo info = new LocationInfo();
                try {
                    JSONObject body = new JSONObject(response);
                    info.setAddress(body.getString("address"));
                    info.setLongitude(location.getLongitude());
                    info.setLatitude(location.getLatitude());
                    if (listener != null) {
                        listener.onSucceed(info);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    if (listener != null) {
                        listener.onFailed();
                    }
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (listener != null) {
                    listener.onFailed();
                }
            }
        });
        Volley.newRequestQueue(mContext).add(request);
    }


    /** 请求lbs定位回调接口 */
    public interface OnGPSLocationRequestListener{
        /** 请求成功 */
        void onSucceed(LocationInfo response);
        /** 请求失败 */
        void onFailed();
    }

}
